package com.muyu.day2zy;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @ClassName jingtaoProductApplication
 * @Description 描述
 * @Author ZeZhang.Liu
 * @Date 2024/3/22 19:36
 */
public class StudentDataInsertion {
    public static void main(String[] args) {
        String url = "jdbc:mysql://118.89.120.67:3306/day2zy";
        String user = "root";
        String password = "csy435732439";
        long startTime = System.currentTimeMillis();

        // 获取当前时间
        LocalDateTime currentTime = LocalDateTime.now();

        // 创建日期时间格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 格式化并打印当前时间
        String formattedTime = currentTime.format(formatter);

        try ( Connection conn = DriverManager.getConnection(url, user, password)) {
            conn.setAutoCommit(false);
            String sql = "INSERT INTO people (name, age, city, addr, sfz, status, create_time) VALUES (?, ?, ?, ?, ?, ?, ?)";
            PreparedStatement pstmt = conn.prepareStatement(sql);

            for (int i = 1; i <= 10000000; i++) {

                String string = generateRandomIDCard();

                pstmt.setString(1, generateRandomChineseName());
                pstmt.setString(2, getAgeFromIDCard(string)+"");
                pstmt.setString(3, getRandomCity());
                pstmt.setString(4, generateRandomAddress());
                pstmt.setString(5, string);
                pstmt.setString(6, "1");
                pstmt.setString(7, formattedTime);
                pstmt.addBatch();

                // Execute batch in smaller chunks to improve performance
                if (i % 1000 == 0) {
                    pstmt.executeBatch();
                    conn.commit();
                }
            }

            // Execute the remaining batch
            pstmt.executeBatch();
            conn.commit();
            conn.setAutoCommit(true);

            long endTime = System.currentTimeMillis();
            long totalTime = endTime - startTime;
            System.out.println("总耗时 " + totalTime + " ms");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 随机生成姓名
     */
    private static final String[] FIRST_NAMES = {"张", "李", "王", "刘", "陈", "杨", "赵", "黄", "周", "吴","崔"};
    private static final String[] LAST_NAMES = {"伟", "芳", "娜", "秀英", "军", "勇", "艳", "杰"};

    public static String generateRandomChineseName() {
        Random random = new Random();
        String firstName = FIRST_NAMES[random.nextInt(FIRST_NAMES.length)];
        String lastName = LAST_NAMES[random.nextInt(LAST_NAMES.length)];

        return firstName + lastName;
    }


    /**
     * 随机生成城市
     */
    private static final List<String> cities = new ArrayList<>();

    static {
        // 初始化城市列表，这里只是示例，你可以添加更多的城市
        cities.add("北京");
        cities.add("上海");
        cities.add("广州");
        cities.add("深圳");
        cities.add("杭州");
        cities.add("成都");
        cities.add("武汉");
        cities.add("南京");
        cities.add("西安");
        cities.add("重庆");
        cities.add("郑州");
        cities.add("长沙");
        cities.add("周口");
    }

    public static String getRandomCity() {
        Random random = new Random();
        if (cities.isEmpty()) {
            throw new IllegalStateException("城市列表为空，无法生成随机城市");
        }
        int index = random.nextInt(cities.size());
        return cities.get(index);
    }

    /**
     * 随机生成详细地址
     */

    private static final List<String> provinces = new ArrayList<>();
    private static final List<String> streets = new ArrayList<>();
    private static final String[] buildingPrefixes = {"小区", "大厦", "公寓", "楼", "园"};
    private static final Random random = new Random();

    static {
        // 初始化省份列表
        provinces.add("北京");
        provinces.add("上海");
        provinces.add("广东");
        provinces.add("江苏");
        provinces.add("浙江");
        provinces.add("山东");
        provinces.add("四川");
        provinces.add("河南");
        provinces.add("湖北");
        provinces.add("湖南");


        // 为了简化，这里假设每个省份下的城市列表是相同的。在实际应用中，你需要为每个省份定义不同的城市列表。
        // 初始化城市列表
        cities.add("北京");
        cities.add("上海");
        cities.add("广州");
        cities.add("深圳");
        cities.add("南京");
        cities.add("杭州");
        cities.add("青岛");
        cities.add("成都");
        cities.add("郑州");
        cities.add("武汉");
        cities.add("长沙");


        // 初始化街道列表
        streets.add("中山路");
        streets.add("人民路");
        streets.add("解放路");
        streets.add("建设路");
        streets.add("黄河路");
        streets.add("长江路");

    }

    public static String getRandomProvince() {
        return provinces.get(random.nextInt(provinces.size()));
    }

    public static String getRandomStreet() {
        return streets.get(random.nextInt(streets.size()));
    }

    public static String getRandomBuildingPrefix() {
        return buildingPrefixes[random.nextInt(buildingPrefixes.length)];
    }

    public static int getRandomBuildingNumber() {
        return 1 + random.nextInt(999); // 生成1到999之间的随机整数
    }

    public static String generateRandomAddress() {
        String province = getRandomProvince();
        String city = getRandomCity();
        String street = getRandomStreet();
        String buildingPrefix = getRandomBuildingPrefix();
        int buildingNumber = getRandomBuildingNumber();

        return province + " " + city + " " + street + " " + buildingPrefix + buildingNumber;
    }

    /**
     * 随机生成身份证
     */
    private static final int ID_CARD_LENGTH = 18;
    private static final String DATE_FORMAT = "yyyyMMdd";
    private static final char[] CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

    public static String generateRandomIDCard() {
        // 生成随机的6位地区码（这里简化为随机数字，实际应为有效的地区码）
        StringBuilder idCard = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            idCard.append(random.nextInt(10));
        }

        // 生成随机的8位出生日期（当前日期前后几年的范围内）
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -random.nextInt(100)); // 随机过去几年
        Date birthDate = calendar.getTime();
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
        try {
            idCard.append(dateFormat.format(birthDate));
        } catch (Exception e) {
            e.printStackTrace();
        }

        //生成随机的3为顺序码
        for(int i=0;i<3;i++){
            idCard.append(random.nextInt(10));
        }

        // 计算校验码
        int sum = 0;
        for (int i = 0; i < ID_CARD_LENGTH - 1; i++) {
            sum += (idCard.charAt(i) - '0') * WEIGHT[i];
        }
        int index = sum % 11;
        idCard.append(CHECK_CODE[index]);

        return idCard.toString();
    }
    /**
     * 根据身份证获取年龄
     */
    private static final int BIRTH_DATE_START_INDEX = 6;
    private static final int BIRTH_DATE_END_INDEX = 14;
    private static final SimpleDateFormat BIRTH_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    /**
     * 从身份证号码获取年龄
     * @param idCard 身份证号码
     * @return 年龄，如果身份证号码格式不正确则返回-1
     */
    public static int getAgeFromIDCard(String idCard) {

        if(idCard == null || idCard.length()!=18){
            return -1;
        }

        String birthDateString = idCard.substring(BIRTH_DATE_START_INDEX, BIRTH_DATE_END_INDEX);
        try {
            Date birthDate = BIRTH_DATE_FORMAT.parse(birthDateString);
            Calendar birthCalendar = Calendar.getInstance();
            birthCalendar.setTime(birthDate);

            Calendar nowCalendar = Calendar.getInstance();
            int age = nowCalendar.get(Calendar.YEAR) - birthCalendar.get(Calendar.YEAR);
            int birthMonth = birthCalendar.get(Calendar.MONTH);
            int nowMonth = nowCalendar.get(Calendar.MONTH);
            if (nowMonth < birthMonth || (nowMonth == birthMonth && nowCalendar.get(Calendar.DAY_OF_MONTH) < birthCalendar.get(Calendar.DAY_OF_MONTH))) {
                age--;
            }
            return age;
        } catch (ParseException e) {
            e.printStackTrace();
            return -1;
        }
    }
}
